﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Net;
using System.Runtime.InteropServices.ComTypes;
using System.Threading;
using System.Windows.Forms;
using Conusic;

namespace ConusicUI
{
    using Conusic.Properties;

    /// <summary>
    /// Description of Auth.
    /// </summary>
    public sealed partial class FormAuth : Form, IAuthorizationCommand
    {
        private Bitmap savedImageGrayForm;

        public FormAuth()
        {
            InitializeComponent();
        }

        private void LinkLabel1LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            System.Diagnostics.Process.Start("http://3po.ru/");
        }

        // костыль для NetFramework 2.0
        private static bool IsNullOrWhiteSpace(string value)
        {
            return String.IsNullOrEmpty(value) || value.Trim().Length == 0;
        }

        private void VkontakteButton1Click(object sender, EventArgs e)
        {
            if (IsNullOrWhiteSpace(textBoxUsername.Text))
            {
                textBoxUsername.Focus();
            }
            else if (IsNullOrWhiteSpace(textBoxPassword.Text))
            {
                textBoxPassword.Focus();
            }
            else
            {
                this.Enabled = false;
                VkontakteAuthorization.ProceedAuthorizationAsync(this, textBoxUsername.Text, textBoxPassword.Text);
            }
        }

        #region FormGrayPaint

        private void AuthEnabledChanged(object sender, System.EventArgs e)
        {
            if (savedImageGrayForm != null)
            {
                savedImageGrayForm.Dispose();
                savedImageGrayForm = null;
            }
            if (Enabled)
            {
                foreach (Control component in Controls)
                {
                    component.Show();
                }
            }
            else
            {
                Point leftTopCorner = this.PointToScreen(new Point(0, 0));
                int heightWithFormDecoration = leftTopCorner.Y - this.Top + this.Height;
                int widhtWithFormDecoration = leftTopCorner.X - this.Left + this.Width;

                var grap = this.CreateGraphics();
                this.savedImageGrayForm = new Bitmap(widhtWithFormDecoration, heightWithFormDecoration);

                this.DrawToBitmap(savedImageGrayForm,
                                  new Rectangle(0, 0, widhtWithFormDecoration, heightWithFormDecoration));

                Graphics a = Graphics.FromImage(savedImageGrayForm);

                float[][] matrixItems = {
                                            new float[]
                                                {
                                                    0.2f,
                                                    0.2f,
                                                    0.2f,
                                                    0,
                                                    0
                                                },
                                            new float[]
                                                {
                                                    0.2f,
                                                    0.2f,
                                                    0.2f,
                                                    0,
                                                    0
                                                },
                                            new float[]
                                                {
                                                    0.2f,
                                                    0.2f,
                                                    0.2f,
                                                    0,
                                                    0
                                                },
                                            new float[]
                                                {
                                                    0,
                                                    0,
                                                    0,
                                                    1,
                                                    0
                                                },
                                            new float[]
                                                {
                                                    0,
                                                    0,
                                                    0,
                                                    0,
                                                    1
                                                }
                                        };
                ColorMatrix colorMatrix = new ColorMatrix(matrixItems);

                // Create an ImageAttributes object and set its color matrix
                ImageAttributes imageAtt = new ImageAttributes();
                imageAtt.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);

                a.DrawImage(savedImageGrayForm,
                            new Rectangle(-leftTopCorner.X + this.Left, -leftTopCorner.Y + this.Top,
                                          widhtWithFormDecoration, heightWithFormDecoration), 0, 0,
                            widhtWithFormDecoration, heightWithFormDecoration, GraphicsUnit.Pixel, imageAtt);

                grap.Dispose();
                foreach (Control component in Controls)
                {
                    component.Hide();
                }
            }
            this.Invalidate();
        }

        private void AuthPaint(object sender, PaintEventArgs e)
        {
            if (savedImageGrayForm != null)
            {
                e.Graphics.DrawImage(savedImageGrayForm, 0, 0);
            }
            else
            {
                e.Graphics.Clear(this.BackColor);
            }
        }

        #endregion

        #region IAuthorizationCommand

        private void FailAuthorization(Exception exception)
        {
            this.Enabled = true;

            this.textBoxUsername.SelectAll();
            this.textBoxUsername.Focus();
            this.textBoxPassword.Text = String.Empty;
            string message;
            const string title = "Ошибка";
            if (exception == null)
            {
                // i don't know what's happening. show error report
                message = null;
                ErrorReport.Show(exception);
            }
            else if (exception is WrongUserNameOrPassword)
            {
                message =
                    "Неверное имя пользователя или пароль.\nИспользуйте авторизационные данные, которые вы используете\nдля входа на сайт Vkontakte.ru.";
            }
            else if (exception is CaptchaException)
            {
                message = "Неправильно введены символы с картинки";
            }
            else if (exception is SavedCookieErrorException)
            {
                message = "Ваша сессия устарела. необходимо заного ввести ваши имя пользователя и пароль";
                this.textBoxPassword.Text = String.Empty;
            }
            else if (exception is WebException)
            {
                message = null;
            }
            else
            {
                message = null;
                ErrorReport.Show(exception,this);
            }

            if (message != null)
            {
                toolTipsError.ToolTipTitle = title;
                toolTipsError.Show(message, this.textBoxUsername);
            }
        }

        private void SuccessAuthorization(string sid)
        {
            Settings.Default.SID = sid;
            Settings.Default.Email = this.textBoxUsername.Text;
            Settings.Default.RememberMe = this.checkBoxRememberMe.Checked;

            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        //костыль для многопоточности
        void IAuthorizationCommand.Execute(string sid)
        {
            this.Invoke(new Action<string>(SuccessAuthorization), sid);
        }

        //костыль для многопоточности
        void IAuthorizationCommand.FailAuthorization(Exception exception)
        {
            this.Invoke((MethodInvoker)delegate { FailAuthorization(exception); });
        }

        private Captcha tempCaptcha = null;

        public Captcha CaptchaHandler
        {
            get
            {
                if (this.tempCaptcha == null)
                {
                    this.tempCaptcha = new CaptchaDialog(this);
                    return tempCaptcha;
                }
                return tempCaptcha;
            }
            set { tempCaptcha = value; }
        }

        #endregion
    }
}